/************************************************************************
int network_inferred (int N, int L, int pathway[L][N], int mode1, int mode2)

Input

N		number of nodes
L		number of steps
pathway		process
mode1		0 : No self-degradation and self-activation ; 1 : Self-degradation ; 2 : Self-degradation and self-activation
mode2		0 : Universal Rule; 1 : Restriction I ; 2 : Restriction II ; 3 : Restriciton I and II

Return Value	1 : Feasible

Note		Consistant Rule
***********************************************************************/

int calc_design (int N, int L, int pathway[L][N], int i, int mode1, int mode2)
{
	int j, k, g[N], r[N], flag, p[L - 1];

	for (j = 0; j < N; j++)
	{
		g[j] = r[j] = -1;
	}

	for (j = 0; j < L - 1; j++)
	{
		p[j] = 0;

		if (pathway[j][i] != pathway[j + 1][i] && (mode2 == 1 || mode2 == 3))
			p[j] = 1;

		if ((j == L - 2 || pathway[j + 1][i] == pathway[j + 2][i]) && (mode2 == 2 || mode2 == 3))
			p[j] = 1;
	}

	for (j = 0; j < L - 1; j++)
	{
		for (k = 0; k < N; k++)
		{
			if (i == k)
				continue;
			if (p[j] == 0 && pathway[j][k] == 0)
				continue;
			if (p[j] == 1 && pathway[j][k] + pathway[j + 1][k] == 0)
				continue;

			/* 0->0 No activation */
			if (pathway[j][i] == 0 && pathway[j + 1][i] == 0)
			{
				g[k] = 0;
			}
			/* 0->1 No inhibition */
			else if (pathway[j][i] == 0 && pathway[j + 1][i] == 1)
			{
				r[k] = 0;
			}
			/* 1->0 No activation */
			else if (pathway[j][i] == 1 && pathway[j + 1][i] == 0)
			{
				g[k] = 0;
			}
			/* 1->1 No inhibition */
			else if (pathway[j][i] == 1 && pathway[j + 1][i] == 1)
			{
				r[k] = 0;
			}
		}
	}

	for (j = 0; j < L - 1; j++)
	{
		/* 1->0 Noticing rii=1 */
		if (pathway[j][i] == 1 && pathway[j + 1][i] == 0)
		{
			flag = 0;
			for (k = 0; k < N; k++)
			{
				if (i == k)
					continue;
				if (p[j] == 0 && pathway[j][k] == 0)
					continue;
				if (p[j] == 1 && pathway[j][k] * pathway[j + 1][k] == 0)
					continue;

				if (r[k] != 0)
				{
					flag ++;
					break;
				}
			}

			if (flag == 0)
			{
				if (mode1 == 0)
					return 0;
				else if (r[i] == -1)
				{
					r[i] = 1;
					g[i] = 0;
				}
				else if (r[i] == 0)
					return 0;
			}
		}
		/* 1->1 Noticing rii=0 */
		else if (pathway[j][i] == 1 && pathway[j + 1][i] == 1)
		{
			if (mode1 == 0)
				continue;

			flag = 0;
			for (k = 0; k < N; k++)
			{
				if (i == k)
					continue;
				if (p[j] == 0 && pathway[j][k] == 0)
					continue;
				if (p[j] == 1 && pathway[j][k] * pathway[j + 1][k] == 0)
					continue;

				if (g[k] != 0)
				{
					flag ++;
					break;
				}
			}

			if (flag == 0)
			{
				if (r[i] == -1)
					r[i] = 0;
				else if (r[i] == 1)
					return 0;
			}
		}
		/* 0->0 Noticing gii=0 */
		else if (pathway[j][i] == 0 && pathway[j + 1][i] == 0)
		{
			if (mode1 != 2)
				continue;

			flag = 0;
			for (k = 0; k < N; k++)
			{
				if (i == k)
					continue;
				if (p[j] == 0 && pathway[j][k] == 0)
					continue;
				if (p[j] == 1 && pathway[j][k] * pathway[j + 1][k] == 0)
					continue;

				if (r[k] != 0)
				{
					flag ++;
					break;
				}
			}

			if (flag == 0)
			{
				if (g[i] == -1)
					g[i] = 0;
				else if (g[i] == 1)
					return 0;
			}
		}
		/* 0->1 Noticing rii=0 */
		else if (pathway[j][i] == 0 && pathway[j + 1][i] == 1)
		{
			flag = 0;
			for (k = 0; k < N; k++)
			{
				if (i == k)
					continue;
				if (p[j] == 0 && pathway[j][k] == 0)
					continue;
				if (p[j] == 1 && pathway[j][k] * pathway[j + 1][k] == 0)
					continue;

				if (g[k] != 0)
				{
					flag ++;
					break;
				}
			}

			if (flag == 0)
			{
				if (mode1 != 2)
					return 0;
				else if (g[i] == -1)
				{
					r[i] = 0;
					g[i] = 1;
				}
				else if (g[i] == 0)
					return 0;
			}
		}
	}

	return 1;
}

int network_inferred (int N, int L, int pathway[L][N], int mode1, int mode2)
{
	int i, NS;

	for (i = 0; i < N; i++)
	{
		NS = calc_design (N, L, pathway, i, mode1, mode2);
		if (NS == 0)
			break;
	}

	if (NS == 0)
		return 0;
	else
		return 1;
}
